home *** CD-ROM | disk | FTP | other *** search
/ Multimedia Jumpstart / Multimedia Microsoft Jumpstart Version 1.1a (Microsoft).BIN / develpmt / source / hotspot / editor / sbcls.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-03  |  24.3 KB  |  639 lines

  1. /**************************************************************************
  2.  *
  3.  *  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  4.  *  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  5.  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  6.  *  PURPOSE.
  7.  *
  8.  *  Copyright (c) 1993  Microsoft Corporation.  All Rights Reserved.
  9.  * 
  10.  **************************************************************************/
  11. /*
  12.  
  13.     sbcls.c --    
  14.         ShowSelectInfo -- Displays hotspot rect info in (modeless) SelectDlg
  15.         DrawSelect -- Draws the selected clip rectangle with its dimensions
  16.             on the DC/screen
  17.         NormalizeRect -- If the rectangle coordinates are reversed, swaps
  18.             them
  19.         TrackMouse -- Draws a rubberbanding rectangle until mouse button up
  20.         Overlap -- Checks for overlapping rectangles; allows overlaps
  21.             rectangles if the frames don't overlap.
  22.         SelectHotspot -- Draw a highlighting rectangle
  23.         PointOnLine - Determines whether the specified point lies on the
  24.             specified line PixelVary is the amount of space allowed on
  25.             either side of the line.
  26.         SizeOK -- Checks if RECT is too small (it would be silly to allow
  27.             1x1 rects)
  28.         PtEdgeRect -- Determines whether the specified point is on the
  29.             edge specified by the rect, including variable distance
  30.             (specified by PixelVary). Returns:    0 = not on edge,
  31.             1 = left, 2 = top, 3 = right, 4 = bottom.
  32.         MoveHotspot -- Given specified POINT (where mouse was clicked),
  33.             will either move a side of the hotspot (thus changing its size)
  34.                 or move the entire hotspot until user releases mouse button
  35.         OnButtonDown -- Deals with mouse button being clicked.  Determines
  36.             whther user is starting a new hotspot, moving a hotspot, or
  37.             selecting a hotspot (i.e. for deletion)
  38.         HotspotFromPoint -- Return a hotspot given a POINT.  Deals with
  39.             appropriate frames.
  40.         OnButtonDblClk -- If double click inside a hotspot, bring up
  41.             Hotspot dialog so user can set options for hotspot.                
  42.         DrawRects -- Draw the hotspot rectangles appropriate for current
  43.             frame or all hotspot rects if frame checking disabled.
  44. */    
  45.  
  46. #include <windows.h>
  47. #include <mmsystem.h>
  48. #include <digitalv.h>
  49. #include <viewer.h>
  50. #include <string.h>
  51.  
  52. #include "hotspot.h"
  53. #include "avihed.h"            /* specific to this program          */
  54. #include "avihede.h"            // extern variable decls
  55. #include "resource.h"
  56.  
  57. /* Macro to swap two values */
  58. #define SWAP(x,y)   ((x)^=(y)^=(x)^=(y))
  59.  
  60. #define MINRECTWIDTH    5
  61. #define MINRECTHEIGHT   5
  62.  
  63. // define VIEWER for use with VIEWER (i.e. for vwrCommand() )
  64.  
  65. /*****************************************************************************************
  66.     FUNCTION:   ShowSelectInfo(RECT FAR *)
  67.         
  68.     PURPOSE:    Displays hotspot rect info in (modeless) SelectDlg
  69. *****************************************************************************************/
  70. void ShowSelectInfo(RECT FAR *prcRect)
  71. {
  72.     if (hwndSelectDlg)
  73.         {
  74.         if (!prcRect)
  75.             {
  76.             SetDlgItemInt(hwndSelectDlg, ID_LEFT, 0, FALSE);
  77.             SetDlgItemInt(hwndSelectDlg, ID_TOP, 0, FALSE);
  78.             SetDlgItemInt(hwndSelectDlg, ID_RIGHT, 0, FALSE);
  79.             SetDlgItemInt(hwndSelectDlg, ID_BOTTOM, 0, FALSE);
  80.             }        
  81.         else
  82.             {                      
  83.             SetDlgItemInt(hwndSelectDlg, ID_LEFT, prcRect->left, FALSE);
  84.             SetDlgItemInt(hwndSelectDlg, ID_TOP, prcRect->top, FALSE);
  85.             SetDlgItemInt(hwndSelectDlg, ID_RIGHT, prcRect->right, FALSE);
  86.             SetDlgItemInt(hwndSelectDlg, ID_BOTTOM, prcRect->bottom, FALSE);
  87.             }        
  88.         }            
  89. }
  90.  
  91. /****************************************************************************
  92.  *                                                                          *
  93.  *  FUNCTION   :  DrawSelect(HDC hdc, BOOL fDraw)                           *
  94.  *                                                                          *
  95.  *  PURPOSE    :  Draws the selected clip rectangle with its dimensions on  *
  96.  *                the DC/screen                                             *
  97.  *                                                                          *
  98.  ****************************************************************************/
  99. void DrawSelect( hdc, prcClip, fDraw)
  100. HDC hdc;
  101. RECT FAR *prcClip;
  102. BOOL fDraw;
  103. {    
  104.  
  105.     HBITMAP hbmp;
  106.     HBRUSH hbr, hbrPrevious;
  107.     
  108.     if (!IsRectEmpty (prcClip)) {  
  109.         hbmp = LoadBitmap(hInst, "Pattern");
  110.         hbr = CreatePatternBrush(hbmp);
  111.     
  112.         UnrealizeObject(hbr);
  113.         hbrPrevious = SelectObject(hdc, hbr);
  114.  
  115.         /* If a rectangular clip region has been selected, draw it */
  116.         PatBlt(hdc, prcClip->left,    prcClip->top,        prcClip->right-prcClip->left, 2,  PATINVERT);
  117.         PatBlt(hdc, prcClip->left,    prcClip->bottom, 2, -(prcClip->bottom-prcClip->top),   PATINVERT);
  118.         PatBlt(hdc, prcClip->right-2, prcClip->top, 2,   prcClip->bottom-prcClip->top,   PATINVERT);
  119.         PatBlt(hdc, prcClip->right,   prcClip->bottom-2, -(prcClip->right-prcClip->left), 2, PATINVERT);
  120.     
  121.         SelectObject(hdc, hbrPrevious);
  122.     
  123.         DeleteObject(hbr);
  124.         DeleteObject(hbmp);            
  125.     }
  126. }
  127. /****************************************************************************
  128.  *                                                                          *
  129.  *  FUNCTION   : NormalizeRect(RECT *prc)                                   *
  130.  *                                                                          *
  131.  *  PURPOSE    : If the rectangle coordinates are reversed, swaps them      *
  132.  *                                                                          *
  133.  ****************************************************************************/
  134. void PASCAL NormalizeRect (prc)
  135. RECT *prc;
  136. {
  137.     if (prc->right < prc->left)
  138.         SWAP(prc->right,prc->left);
  139.     if (prc->bottom < prc->top)
  140.         SWAP(prc->bottom,prc->top);
  141. }
  142.  
  143. /****************************************************************************
  144.  *                                                                          *
  145.  *  FUNCTION   : TrackMouse(HWND hwnd, POINT pt)                            *
  146.  *                                                                          *
  147.  *  PURPOSE    : Draws a rubberbanding rectangle until mouse button up      *
  148.  *                                                                          *
  149.  ****************************************************************************/
  150. void TrackMouse (hwnd, pt, prcClip)
  151. HWND hwnd;
  152. POINT pt;
  153. RECT *prcClip;
  154. {
  155.     HDC   hdc;
  156.     MSG   msg;
  157.     RECT  rcClient;    
  158.  
  159.     hdc = GetDC(hwnd);
  160.     SetCapture(hwnd);
  161.  
  162.     GetClientRect(hwnd,&rcClient);
  163.  
  164.     /* Display the coordinates */
  165.     DrawSelect(hdc, prcClip, FALSE);
  166.  
  167.     /* Initialize clip rectangle to the point */
  168.     
  169.     prcClip->left   = pt.x;
  170.     prcClip->top    = pt.y;
  171.     prcClip->right  = pt.x;
  172.     prcClip->bottom = pt.y;
  173.  
  174.     /* Eat mouse messages until a WM_LBUTTONUP is encountered. Meanwhile
  175.      * continue to draw a rubberbanding rectangle and display it's dimensions
  176.      */
  177.     for (;;){
  178.     if (GetMessage(&msg,NULL,WM_MOUSEFIRST,WM_MOUSELAST)){
  179.  
  180.         DrawSelect(hdc,prcClip, FALSE);
  181.  
  182.             prcClip->left   = pt.x;
  183.             prcClip->top    = pt.y;
  184.             prcClip->right  = LOWORD(msg.lParam);
  185.             prcClip->bottom = HIWORD(msg.lParam);
  186.  
  187.             NormalizeRect(prcClip);
  188.             DrawSelect(hdc, prcClip, TRUE);
  189.             ShowSelectInfo(prcClip);
  190.  
  191.             if (msg.message == WM_LBUTTONUP)
  192.                 break;
  193.         }
  194.     else
  195.         continue;
  196.     }
  197.  
  198.     ReleaseCapture();
  199.     ReleaseDC(hwnd,hdc);
  200. }
  201.  
  202. /*****************************************************************************************
  203.  
  204.     FUNCTION:   Overlap(PMOVIEINFO, RECT, PHOTSPOT)
  205.     
  206.     PURPOSE:    Checks for overlapping rectangles; allows overlaps rectangles
  207.                 if the frames don't overlap.  i.e., rect1 at 10,10,50,50
  208.                 where BeginFrame=0, EndFrame=10 and rect2 at 12,12,40,40
  209.                 where BeginFrame=11, EndFrame=125 is ok.
  210.     
  211.     PARAMS:     PMOVIEINFO  - far pointer to a MOVIEINFO struct
  212.                 RECT        - rectangle to check against all others
  213.                 PHOTSPOT    - far pointer to current hotspot (e.g. in case we're moving
  214.                               a hotspot, don't check it against itself); this can be NULL
  215.                               
  216.     RETURNS:    TRUE        - rect overlaps another one
  217.                 FALSE       - rect does not overlap                              
  218. *****************************************************************************************/                                                                       
  219. BOOL Overlap(PMOVIEINFO pMovieInfo, RECT rc, PHOTSPOT pThisHotspot)
  220. {
  221.  
  222.     PHOTSPOT pHotspot;
  223.     RECT rcIntersect;
  224.     
  225.     pHotspot = pMovieInfo->pHotspotList;
  226.     
  227.     while (pHotspot)
  228.         {
  229.         
  230.             if (pHotspot != pThisHotspot)
  231.                 {                
  232.                 if (IntersectRect(&rcIntersect, &pHotspot->rc, &rc))
  233.                     {                 
  234.                     if (!pThisHotspot)
  235.                         {
  236.                         if (pMovieInfo->dwCurrentFrame >= pHotspot->BeginFrame && 
  237.                                     pMovieInfo->dwCurrentFrame <= pHotspot->EndFrame)
  238.                             return TRUE;
  239.                         }
  240.                     else
  241.                         {                        
  242.                         if (pThisHotspot->EndFrame < pHotspot->BeginFrame ||
  243.                                 pThisHotspot->BeginFrame > pHotspot->EndFrame)
  244.                             ;                                                                            
  245.                         else                    
  246.                             return TRUE;
  247.                         }
  248.                     }
  249.                 }
  250.              
  251.         pHotspot = pHotspot->pNext;            
  252.         }
  253.     return FALSE;        
  254. }
  255.  
  256.  
  257. /*****************************************************************************************
  258.     FUNCTION:   SelectHotspot(PMOVIEINFO, PHOTSPOT)
  259.     
  260.     PURPOSE:    Draw a highlighting rectangle
  261.     
  262.     NOTES:      Not implemented; instead the SelectDlg is updated with the
  263.                 coordinates of the current rect.
  264. *****************************************************************************************/
  265. BOOL SelectHotspot(PMOVIEINFO pMovieInfo, PHOTSPOT pHotspot)
  266. {    
  267.     return TRUE;   
  268. }
  269.  
  270. /*****************************************************************************************
  271.     FUNCTION:   PointOnLine(POINT, int, int, int int)
  272.     
  273.     PURPOSE:    Determines whether the specified point lies on the specified line
  274.     
  275.     NOTES:      PixelVary is the amount of space allowed on either side of the line.
  276. *****************************************************************************************/
  277. BOOL PointOnLine(POINT pt, int x1, int y1, int x2, int y2)
  278. {
  279.  
  280. //      old way of checking: doesn't allow variable space
  281. //    if (pt.x <= x2 && pt.x >= x1 && pt.y <= y2 && pt.y >= y1)
  282.  
  283.     if ((pt.x >= x1 - PixelVary && pt.x <= x1 + PixelVary) ||
  284.         (pt.x >= x2 - PixelVary && pt.x <= x2 + PixelVary) ||
  285.         (pt.y >= y1 - PixelVary && pt.y <= y1 + PixelVary) ||
  286.         (pt.y >= y2 - PixelVary && pt.y <= y2 + PixelVary))
  287.         return (TRUE);
  288.     else
  289.         return (FALSE);        
  290. }
  291.  
  292.  
  293. /*****************************************************************************************
  294.     FUNCTION:   SizeOK(RECT)
  295.     
  296.     PURPOSE:    Checks if RECT is too small (it would be silly to allow 1x1 rects)
  297. *****************************************************************************************/
  298. BOOL SizeOK(RECT rc)
  299. {               
  300.     if (rc.right - rc.left < MINRECTWIDTH)
  301.         return FALSE;
  302.     if (rc.bottom - rc.top < MINRECTHEIGHT)
  303.         return FALSE;
  304.  
  305.     return TRUE;
  306. }
  307.  
  308. /*****************************************************************************************
  309.     FUNCTION:   PtEdgeRect(RECT, POINT)
  310.     
  311.     PURPOSE:    Determines whether the specified point is on the edge specified by
  312.                 the rect, including variable distance (specified by PixelVary).
  313.                 Returns:    0 = not on edge
  314.                             1 = left
  315.                             2 = top
  316.                             3 = right
  317.                             4 = bottom            
  318. *****************************************************************************************/
  319. int PtEdgeRect(RECT rc, POINT pt)
  320. {
  321.     int PtOnLine = 0;
  322.     RECT rcTemp;
  323.  
  324.     SetRect(&rcTemp, rc.left - PixelVary, rc.top, rc.left + PixelVary, rc.bottom);
  325.     if (PtInRect(&rcTemp, pt))        
  326.         PtOnLine = 1;        
  327.     SetRect(&rcTemp, rc.left, rc.top - PixelVary, rc.right, rc.top + PixelVary);
  328.     if (PtInRect(&rcTemp, pt))
  329.         PtOnLine = 2;
  330.     SetRect(&rcTemp, rc.right - PixelVary, rc.top, rc.right + PixelVary, rc.bottom);
  331.     if (PtInRect(&rcTemp, pt))
  332.         PtOnLine = 3;
  333.     SetRect(&rcTemp, rc.left, rc.bottom - PixelVary, rc.right, rc.bottom + PixelVary);
  334.     if (PtInRect(&rcTemp, pt))
  335.         PtOnLine = 4;        
  336.  
  337.     return (PtOnLine);    
  338. }
  339.  
  340. /*****************************************************************************************
  341.     FUNCTION:   MoveHotspot(PMOVIEINFO, PHOTSPOT, POINT)
  342.     
  343.     PURPOSE:    Given specified POINT (where mouse was clicked), will either
  344.                 move a side of the hotspot (thus changing its size)
  345.                 or move the entire hotspot until user releases mouse button
  346.                 
  347.     RETURNS:    TRUE                            
  348. *****************************************************************************************/
  349. BOOL MoveHotspot(PMOVIEINFO pMovieInfo, PHOTSPOT pHotspot, POINT pt)
  350. {
  351.     MSG msg;
  352.     RECT rc;
  353.     HDC hDC;
  354.     int PtOnLine = 0; // 0 = not on line, 1 = left, 2 = top, 3= right, 4= bottom
  355.     //HCURSOR hcurSave;
  356.     //RECT rcTemp;
  357.     RECT rcOld;
  358.     
  359.     CopyRect(&rc, &pHotspot->rc);
  360.     
  361.     PtOnLine = PtEdgeRect(rc, pt);
  362.     hDC = GetDC(pMovieInfo->hwndMovie);
  363.  
  364.     for (;;)
  365.         {
  366.         if (GetMessage(&msg,NULL,WM_MOUSEFIRST,WM_MOUSELAST))
  367.             {            
  368.             DrawSelect(hDC,&rc, FALSE);
  369.             CopyRect(&rcOld, &rc);
  370.                 switch (PtOnLine)
  371.                     {
  372.                     case 0:                
  373.                         rc.left   = rc.left + LOWORD(msg.lParam) - pt.x;
  374.                         rc.top    = rc.top + HIWORD(msg.lParam) - pt.y;
  375.                         rc.right  = rc.right + LOWORD(msg.lParam) - pt.x;
  376.                         rc.bottom = rc.bottom + HIWORD(msg.lParam) - pt.y;
  377.                         break;
  378.                     
  379.                     case 1:                    
  380.                         rc.left   = rc.left + LOWORD(msg.lParam) - pt.x; 
  381.                         break;
  382.                 
  383.                     case 2:
  384.                         rc.top    = rc.top + HIWORD(msg.lParam) - pt.y;
  385.                         break;
  386.  
  387.                     case 3:
  388.                         rc.right  = rc.right + LOWORD(msg.lParam) - pt.x;
  389.                         break;
  390.                     
  391.                     case 4:                    
  392.                         rc.bottom = rc.bottom + HIWORD(msg.lParam) - pt.y;
  393.                         break;                                    
  394.                     
  395.                     }                
  396.                 pt.x = LOWORD(msg.lParam);
  397.                 pt.y = HIWORD(msg.lParam);
  398.                 NormalizeRect(&rc);
  399.                 DrawSelect(hDC, &rc, TRUE);            
  400.                 ShowSelectInfo(&rc);
  401.                 if (!EqualRect(&rcOld, &rc))
  402.                     bModified = TRUE;
  403.             if (msg.message == WM_LBUTTONUP)
  404.                 break;
  405.             } // getmessage
  406.         else
  407.             continue;
  408.         }
  409.         
  410.     
  411.     if (!Overlap(pMovieInfo, rc, pHotspot) && SizeOK(rc))
  412.         CopyRect(&pHotspot->rc, &rc);
  413.     else
  414.         {
  415.         DrawSelect(hDC, &rc, TRUE);
  416.         DrawSelect(hDC, &pHotspot->rc, TRUE);        
  417.         }        
  418.     
  419.     ReleaseDC(pMovieInfo->hwndMovie, hDC);    
  420. //    if (PtOnLine != 0)
  421. //        SetCursor(hcurSave);
  422.     
  423.     return TRUE;
  424.  
  425. }
  426.  
  427. /*****************************************************************************************
  428.     FUNCTION:   OnButtonDown(PMOVIEINFO, USHORT, UHSORT, LONG)
  429.     
  430.     PURPOSE:    Deals with mouse button being clicked.
  431.                 Posibilities:   - starting a new hotspot
  432.                                 - moving a hotspot
  433.                                 - selecting a hotspot (i.e. for deletion)
  434.                                 
  435.     RETURNS:    0 = nothing happened (e.g. there was an overlap) or unable to alloc memory
  436.                 1 = no longer used
  437.                 2 = hotspot selected/drawn etc. (in any case, make the hotspot selected
  438.                     in case of double click)                
  439. *****************************************************************************************/
  440. int OnButtonDown(PMOVIEINFO pMovieInfo, USHORT msg, USHORT wp, LONG lp)
  441. {
  442.     PHOTSPOT pHotspot, pHotspotSelected = NULL;
  443.     DWORD dwFrame;                      
  444.     POINT pt;    
  445.     RECT rc;
  446.     
  447.     if (!pMovieInfo)
  448.         return FALSE;
  449.     
  450.     pHotspot = pMovieInfo->pHotspotList;
  451.     pt = MAKEPOINT(lp);
  452.     dwFrame = GetMovieFrame(pMovieInfo);
  453.     SetRectEmpty(&rc);
  454.  
  455.     if (!pHotspot)                          // none selected yet...
  456.         {
  457.         TrackMouse(pMovieInfo->hwndMovie, pt, &rc);
  458.         if ((pHotspot = (PHOTSPOT)ALLOCATE(sizeof(HOTSPOT))))
  459.              {            
  460.             CopyRect(&pHotspot->rc, &rc);
  461.             pHotspot->BeginFrame = pMovieInfo->dwCurrentFrame;
  462.             pHotspot->EndFrame = pMovieInfo->dwMovieLength;        
  463.             pHotspot->pszCommand = NULL;
  464.             pHotspot->pszHotspotID = NULL;
  465.             pHotspot->OnClick = ID_CONTINUE;
  466.             AddHotspot(pMovieInfo, pHotspot);        
  467.             bModified = TRUE;
  468.             return (2);
  469.             }
  470.         }
  471.     else
  472.         {
  473.         while (pHotspot)
  474.         {        
  475.         if (pMovieInfo->dwCurrentFrame >= pHotspot->BeginFrame && 
  476.                     pMovieInfo->dwCurrentFrame <= pHotspot->EndFrame)        
  477.             {
  478. //            if (PtInRect(&pHotspot->rc, pt) != 0)
  479.               if (PtEdgeRect(pHotspot->rc, pt) || PtInRect(&pHotspot->rc, pt))
  480.                 // if the point's in the rect, select the rect
  481.                 // otherwise, draw a new rect.
  482.                 // need more complicated code for good handling of overlapping rects
  483.                 {                                                
  484.                 pHotspotSelected = pHotspot;
  485.                 }                            
  486.             }
  487.         pHotspot = pHotspot->pNext;       
  488.         } // while
  489.         if (pHotspotSelected)
  490.             {
  491.             // we can move the rect, resize it, delete it, or if dlbclick, bring up dlg                        
  492.             SelectHotspot(pMovieInfo, pHotspotSelected);
  493.             MoveHotspot(pMovieInfo, pHotspotSelected, pt);
  494.             ShowSelectInfo(&pHotspotSelected->rc);
  495.                         
  496.             return (2);            
  497.             }
  498.         else
  499.             {
  500.             TrackMouse(pMovieInfo->hwndMovie, pt, &rc);        
  501.             if (Overlap(pMovieInfo, rc, NULL) || !SizeOK(rc))
  502.                 {
  503.                 HDC hDC;
  504.             
  505.                 hDC = GetDC(pMovieInfo->hwndMovie);
  506.                 DrawSelect(hDC, &rc, TRUE);                 // un-invert the rect
  507.                 ReleaseDC(pMovieInfo->hwndMovie, hDC);
  508.                 ShowSelectInfo(NULL);
  509.                 return FALSE;
  510.                 }
  511.             if (! (pHotspot = (PHOTSPOT)ALLOCATE(sizeof(HOTSPOT))))
  512.                 {
  513.                 return (FALSE);
  514.                 }
  515.             else
  516.                 {
  517.                 CopyRect(&pHotspot->rc, &rc);
  518.                 pHotspot->BeginFrame = pMovieInfo->dwCurrentFrame;
  519.                 pHotspot->EndFrame = pMovieInfo->dwMovieLength;            
  520.                 pHotspot->pszCommand = NULL;
  521.                 pHotspot->pszHotspotID = NULL;
  522.                 pHotspot->OnClick = ID_CONTINUE;
  523.                 AddHotspot(pMovieInfo, pHotspot);        
  524.                 bModified = TRUE;
  525.                 return (2);
  526.                 }            
  527.             }
  528.         
  529.         } // else
  530.         
  531.     return TRUE;        
  532. }
  533.  
  534. /*****************************************************************************************
  535.     FUNCTION:   HotspotFromPoint(PMOVIEINFO, POINT)
  536.     
  537.     PURPOSE:    Return a hotspot given a POINT.  Deals with appropriate frames.
  538. *****************************************************************************************/
  539. PHOTSPOT HotspotFromPoint(PMOVIEINFO pMovieInfo, POINT pt)
  540. {
  541.     PHOTSPOT pHotspot, pHotspotSelected = (PHOTSPOT)NULL;
  542.  
  543.     pHotspot = pMovieInfo->pHotspotList;
  544.     
  545.     while (pHotspot)
  546.         {        
  547.         if (bShowValidRectsOnly)
  548.             {            
  549.             if (pHotspot->BeginFrame <= pMovieInfo->dwCurrentFrame && 
  550.                         pMovieInfo->dwCurrentFrame <= pHotspot->EndFrame)
  551.                 {
  552.                 if (PtInRect(&pHotspot->rc, pt) != 0)
  553.                     pHotspotSelected = pHotspot;
  554.                 }
  555.             }
  556.         else
  557.             {
  558.             if (PtInRect(&pHotspot->rc, pt) != 0)
  559.                 pHotspotSelected = pHotspot;                
  560.             }            
  561.         pHotspot = pHotspot->pNext;
  562.         } // while
  563.         
  564.     return (pHotspotSelected);
  565. }
  566.  
  567. /*****************************************************************************************
  568.     FUNCTION:   OnButtonDblClk(PMOVIEINFO, USHORT, unsigned, LONG)
  569.     
  570.     PURPOSE:    If double click inside a hotspot, bring up Hotspot dialog so
  571.                 user can set options for hotspot.                
  572. *****************************************************************************************/
  573. int OnButtonDblClk(PMOVIEINFO pMovieInfo, USHORT msg, unsigned wp, LONG lp)
  574. {
  575.     static DLGPROC dlgproc;
  576.     POINT pt;
  577.     PHOTSPOT pHotspotSelected = NULL, pHotspot;
  578.  
  579.     pt = MAKEPOINT(lp); 
  580.     
  581.     pHotspot = pMovieInfo->pHotspotList;
  582.     
  583.     while (pHotspot)
  584.         {        
  585.         if (bShowValidRectsOnly)
  586.             {            
  587.             if (pHotspot->BeginFrame <= pMovieInfo->dwCurrentFrame && 
  588.                         pMovieInfo->dwCurrentFrame <= pHotspot->EndFrame)
  589.                 {
  590.                 if (PtInRect(&pHotspot->rc, pt) != 0)
  591.                     pHotspotSelected = pHotspot;
  592.                 }
  593.             }
  594.         else
  595.             {
  596.             if (PtInRect(&pHotspot->rc, pt) != 0)
  597.                 pHotspotSelected = pHotspot;                
  598.             }            
  599.         pHotspot = pHotspot->pNext;
  600.         } // while
  601.     if (pHotspotSelected)
  602.         {
  603.         dlgproc = (DLGPROC) MakeProcInstance(HotspotDlg, hInst);
  604.         DialogBoxParam(hInst, MAKEINTRESOURCE(HOTSPOTDLG), pMovieInfo->hwndParent, dlgproc,
  605.                 (LPARAM)pHotspotSelected);
  606.         FreeProcInstance((FARPROC)dlgproc);
  607.         InvalidateRect(pMovieInfo->hwndMovie, NULL, TRUE);
  608.         UpdateWindow(pMovieInfo->hwndMovie);
  609.         }
  610.     return TRUE;
  611. }
  612.  
  613. /*****************************************************************************************
  614.     FUNCTION:   DrawRects(HDC, PMOVIEINFO)
  615.     
  616.     PURPOSE:    Draw the hotspot rectangles appropriate for current frame
  617.                 or all hotspot rects if frame checking disabled.
  618. *****************************************************************************************/
  619. void DrawRects(HDC hDC, PMOVIEINFO pMovieInfo)
  620. {
  621.     PHOTSPOT pHotspot;
  622.     
  623.     pHotspot = pMovieInfo->pHotspotList;
  624.     
  625.     while (pHotspot)
  626.         {
  627.         if (bShowValidRectsOnly)
  628.             {
  629.             if (pHotspot->BeginFrame <= pMovieInfo->dwCurrentFrame &&
  630.                     pHotspot->EndFrame >= pMovieInfo->dwCurrentFrame)
  631.                 DrawSelect(hDC, &pHotspot->rc, TRUE);        
  632.             }
  633.         else
  634.             DrawSelect(hDC, &pHotspot->rc, TRUE);
  635.                                     
  636.         pHotspot = pHotspot->pNext;
  637.         }
  638. }
  639.